import { ModuleWithProviders, NgModule, Optional, SkipSelf } from '@angular/core';
import { throwIfAlreadyLoaded } from './module-import-guard';
import { I18NService } from './i18n/i18n.service';
import { HttpService } from '@core/services/http/http.service';
import { ConfigService } from '@core/config/config.service';
import { GridConfigService } from '@core/config/grid-config.service';
import { SearchService } from '@core/services/search.service';
import { ApiService } from '@core/services/http/api.service';
import { Events } from '@core/services/events/Events';
import { SubjectService } from '@core/services/events/subject.service';
import { ExpressionService } from '@core/services/expression/ExpressionService';
import {
  ScrollService,
  TitleService,
  MenuService, SettingsService, WINDOW,
} from '@core';
import { APP_I18N_TOKEN, AppI18NServiceFake } from '@core/services/i18n/i18n';
import { CommonModule } from '@angular/common';

import { ApesContextMenuService } from '@shared/ag-grid-ext/context-menu/context-menu.service';
import { ExpressionServiceSimple } from '@core/services/expression/ExpressionService-simple';

const SERVICES = [
  MenuService,
  ScrollService,
  SettingsService,
  TitleService,
  I18NService,
  ConfigService,
  GridConfigService,
  SearchService,
  ExpressionService,
  ExpressionServiceSimple,
  DialogInputService,
  HttpService,
  ApiService,
  Events,
  LoggerService,
  SubjectService,
  UtilsService,
  WebsocketService,
  NotificationsService,
  ApesLoginComponent,
  ApesContextMenuService,
  AddPanelComponent,
  FormService,
  AreaService,
  ButtonService,
  DownloadService,
  ImportService,
  HtmlToCanvasService,
  LinkService
];
// components
const COMPONENTS = [];
// pipes
import { DatePipe } from './pipes/date/date.pipe';
import { CNCurrencyPipe } from './pipes/currency/cn-currency.pipe';
import { KeysPipe } from './pipes/keys/keys.pipe';
import { YNPipe } from './pipes/yn/yn.pipe';
import { DataFormatPipe } from '@core/pipes/dataformat/data-format.pipe';
import { UtilsService } from '@core/services/expression/utils.service';
import { WebsocketService } from '@core/services/websocket/websocket.service';
import { LoggerService } from '@core/services/logger.service';
import { NotificationsService } from '@core/services/notification/notification.service';
import { DialogInputService } from '@core/services/dialog-input.service';
import { ApesModalRef } from '@shared/apes/modal';
import { ApesLoginComponent } from '@shared/apes-login';
import { AddPanelComponent } from '../routes/e-commerce/adminPanel/addPanel/addPanel.component';
import { FormService } from '@core/services/form.service';
import { AreaService } from '@core/services/masterdata/area.service';
import { ButtonService } from '@core/services/button.service';
import { DownloadService } from '@core/services/tool/download.service';
import { ImportService } from '@core/services/tool/import.service';
import { HtmlToCanvasService } from '@core/services/tool/htmlToCanvas.service';
import { LinkService } from '@core/services/tool/link.service';

const PIPES = [DataFormatPipe, DatePipe, CNCurrencyPipe, KeysPipe, YNPipe];

@NgModule({
  imports: [
    CommonModule,
  ],
  declarations: [...PIPES],
  exports: [...COMPONENTS, ...PIPES],
})
export class CoreModule {
  constructor(
    @Optional()
    @SkipSelf()
      parentModule: CoreModule,
  ) {
    throwIfAlreadyLoaded(parentModule, 'CoreModule');
  }

  static forRoot(): ModuleWithProviders {
    return <ModuleWithProviders>{
      ngModule: CoreModule,
      providers: [
        { provide: APP_I18N_TOKEN, useClass: AppI18NServiceFake },
        { provide: WINDOW, useValue: window },
        { provide: ApesModalRef },
        ...SERVICES,
      ],
    };
  }
}
